<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    // 原型 [[Prototype]]
    // 所有的实例化对象都有原型属性([[Prototype]]),指向创建它的构造函数的原型对象
    // 实例化对象[[Prototype]]  => 构造函数.prototype

    // 原型链
    // 实例对象在查找属性和方法时的链式查找机制(顺着原型找)

    function Cat(name,color){
        this.name = name;
        this.color = color;
    }

    Cat.prototype.species = "Cat";
    Cat.prototype.skill = function(){
        console.log("捉老鼠");
    }
    Cat.prototype.call = function(){
        console.log("喵喵");
    }
    Cat.prototype.say = function(){
        console.log(this.name,this.color);
    }

    Object.prototype.a = 1;
    Object.prototype.b = 2;
    
    var Tom = new Cat("Tom","black");
    console.log(Tom);


    // 实例化对象查找属性和方法的过程中
    // 1. 实例化对象自己有, 找自己的
    // console.log(Tom.name,Tom.color);

    // 2. 实例化对象自己没有,顺着原型属性[[Prototype]],找指向创建它的构造函数的原型对象(Cat.prototype)
    // console.log(Tom.species);
    // console.log(Tom.skill);
    // console.log(Tom.call);
    // console.log(Tom.say);

    // 3. 如果构造函数的原型对象上也找不到到属性和方法, 继续顺着原型属性[[Prototype]],找Object.prototype(构造函数的原型对象 -> 对象数据(实例化对象 -> 是由构造函数Object创建的))
    
    // 注意:
    // 构造函数的原型对象,本质也是一个对象(实例化对象 => 它是由哪个构造函数创建的?  => Object)
    
    // console.log(Cat.prototype); // 对象
    // console.log(Cat.prototype.__proto__ === Object.prototype); // 原型对象的原型指向
    // console.log(Object.getPrototypeOf(Cat.prototype) === Object.prototype); // 原型对象的原型指向

    // console.log(Tom.a);
    // console.log(Tom.b);
    // console.log(Tom.toString()); // "[object Object]"


    // 4. 如果Object.prototype上找不到到属性和方法, 

    // 根据3类推: (错误)
    // Object.prototype也是一个对象 -> 它是由谁创建的 -> 是由构造函数Object创建的  => 矛盾
    // 1. Object创建了Object自己的原型对象  
    // 2. 如果Object.prototype上找不到到属性和方法 => 继续顺着原型属性[[Prototype]],找Object.prototype (自己找不到 继续找 自己 => 死查找)

    // 官方强制规定
    // 1. Object.prototype.__proto__ = null    => 如果属性在Object上找不到,不在向后查找 默认返回undefined

    // console.log(Object.prototype);

    // console.log(Tom.hello);


</script>
</html>